# LuckPay Web Manage System
#
# Copyright (c) 2016 Lucky Byte, Inc.
#
express = require 'express'
pgsql   = require 'pg'
uuid    = require 'uuid'
secure  = require '../lib/secure'
router = express.Router()
module.exports = router


router.get '/', (req, res, next) ->
    # 检查用户权限
    for perm in req.session.userinfo.permission
        if perm.href is '/merch'
            if not perm.permission.new
                return next new Error('您没有新增商户的权限')
        if perm.href is '/terms'
            if not perm.permission.new
                return next new Error('您没有新增终端的权限')

    await pgsql.connect settings.pgsql_url, defer err, client, done
    if err then done(client); return next(err)

    # 手续费列表
    await client.query \
        "select * from pay_fee", defer err, result
    if err then done(client); return next(err)
    res.locals.fees = result.rows

    # 交易控制列表
    await client.query "select * from pay_trctl_t", defer err, result
    if err then done(client); return next(err)
    res.locals.trctl_list = result.rows
    done()

    # 查询代理商资金池
    await client.query \
        "select * from pay_p2_fund order by name", defer err, result
    if err then done(client); return next(err)
    res.locals.p2_funds = result.rows

    res.render 'wizard/index', record: {}


router.post '/ajax/pay_merids', (req, res, next) ->
    res.type 'json'
    for k in ['chnl']
        return next(new Error("请求缺少参数[#{k}]")) if not req.body[k]

    await pgsql.connect settings.pgsql_url, defer err, client, done
    if err then done(client); return next(err)

    await client.query "select * from pay_merch where
        chnl = $1 and inside = false and
        disabled = false and shaded = false", [
            req.body.chnl
        ], defer err, result
    if err then done(client); return next(err)
    done()
    res.json succ: true, merids: result.rows


# 查询交易控制信息
router.post '/ajax/trctl', (req, res, next) ->
    res.type('json')
    for k in ['trctl_uuid', 'trcode' ]
        return next(new Error("请求缺少参数[#{k}]")) if not req.body[k]

    await pgsql.connect settings.pgsql_url, defer err, client, done
    if err then done(client); return next(err)

    await client.query "select * from pay_trctl_t where uuid = $1", [
            req.body.trctl_uuid
        ], defer err, result
    if err then done(client); return next(err)
    done()

    record = result.rows[0]
    res.json succ: true, trctl: record.trctl[req.body.trcode]


# 统一去除空白字符
router.use (req, res, next) ->
    return next() if not req.body or not req.body.info

    nospaces = [
        't20_merno', 'tz0_merno', 't20_termid', 'tz0_termid',
        't60_merno', 'tz1_merno', 't60_termid', 'tz1_termid',
        'acct_no', 'acct_name', 'acct_cred_no'
    ]
    for k, v of req.body.info
        if typeof(v) is 'string' and req.body.info.hasOwnProperty(k)
            if k in nospaces
                req.body.info[k] = v.replace(/\s/g, '')
            else
                req.body.info[k] = v.trim()
    next()


# 消费代付商户入户检查
router.post '/finish/p1', (req, res, next) ->
    res.type 'json'
    for k in ['t20_merno', 't20_termid', 'name', 'contact', 'address',
        'tz0_merno', 'tz0_termid', 'tz0_tmk',
        't20_fee', 'acct_no', 'pay_chnl', 'pay_merid']
        if not req.body.info[k] or req.body.info[k].length == 0
            return next(new Error("请求缺少参数[#{k}]"))

    acct_name = req.body.info.acct_name or ''
    acct_cred_no = req.body.info.acct_cred_no or ''
    if acct_name.trim().length == 0 and acct_cred_no.trim().length == 0
        return next new Error('开户人姓名与证件号码必须输入一项')

    await pgsql.connect settings.pgsql_url, defer err, client, done
    if err then done(client); return next(err)

    # 查询商户是否已经存在
    await client.query "select * from pay_merch
        where chnl = 1 and merno in ($1, $2)", [
            req.body.info.t20_merno, req.body.info.tz0_merno
        ], defer err, result
    if err then done(client); return next(err)
    if result.rows.length > 0
        done()
        return next new Error("商户 #{req.body.info.t20_merno} 或 " +
            "#{req.body.info.tz0_merno} 已存在，请检查...")

    # 查询待复核表中是否有此商户信息
    await client.query "select m.*, u.realname as user
        from pay_merch_ex as m
        left join web_users as u on u.uuid = m.inputer
        where m.chnl = 1 and m.merno in ($1, $2)", [
            req.body.info.t20_merno, req.body.info.tz0_merno
        ], defer err, result
    if err then done(client); return next(err)
    done()
    if result.rows.length > 0
        return next new Error("商户 #{req.body.info.t20_merno} 或 " +
            "#{req.body.info.tz0_merno} 已被用户 " +
            "#{result.rows[0].user} 添加，尚未复核或尚未生效")
    next()


# 在一个事务中处理
router.post '/finish/p1', (req, res, next) ->
    await pgsql.connect settings.pgsql_url, defer err, client, done
    if err then done(client); return next(err)

    await client.query "begin", defer err, result
    if err then done(client); return next(err)

    req.client = client
    req.done = done
    next()

# 增加消费商户
router.post '/finish/p1', (req, res, next) ->
    trctl =
        t20 : {
            time_begin:     req.body.info.time_begin
            time_end:       req.body.info.time_end
            min_amt_per:    req.body.info.min_amt_per
            min_amt_per2:   req.body.info.min_amt_per2
            max_amt_per:    req.body.info.max_amt_per
            max_amt_per2:   req.body.info.max_amt_per2
            max_amt_minute: req.body.info.max_amt_minute
            max_cnt_minute: req.body.info.max_cnt_minute
            max_amt_day:    req.body.info.max_amt_day
            max_cnt_day:    req.body.info.max_cnt_day
        }
        trcodes : {
            t1: true, t2: true, t3: true, t4: true, t5: true,
            t10: true, t20: true
        }
    # 在商户信息表中添加一条影子记录，用于终端可以引用未复核的商户
    merch_uuid = uuid.v4()
    await req.client.query "insert into pay_merch (
            shaded, uuid, inside, chnl, merno, name, trctl, inputer, checker
        ) values (
            true, $1, $2, $3, $4, $5, $6, $7, $8
        ) returning serial", [
            merch_uuid, false, 1,
            req.body.info.t20_merno, req.body.info.name,
            JSON.stringify(trctl),
            req.session.userinfo.uuid, req.session.userinfo.uuid,
        ], defer err, result
    if err then req.done(req.client); return next(err)
    merch_serial = result.rows[0].serial

    # 添加商户信息到待复核表
    merch_uuid_ex = uuid.v4()
    await req.client.query "insert into pay_merch_ex (
            uuid,              inside,         chnl,           merno,
            t20_fee,           trctl,          settl_merid,    mapto_merid,
            name,              contact,        telephone,      mobile,
            fax,               email,          address,
            unit_name,         unit_name_abbr, unit_english,     unit_english_abbr,
            unit_code,         unit_license,   unit_license_exp, unit_tax_code,
            unit_issuer,       unit_address,   unit_type,        unit_legal_name,
            unit_cred_type,    unit_cred_no,   unit_assets,      unit_scope,
            keys,              notes,
            ref_serial,        ref_uuid,
            inputer,           input_time,     action
        ) values (
            $1, $2, $3, $4, $5, $6, $7, $8,
            $9, $10, $11, $12, $13, $14, $15,
            $16, $17, $18, $19, $20, $21, $22, $23,
            $24, $25, $26, $27, $28, $29, $30, $31,
            $32, $33,
            $34, $35,
            $36, CURRENT_TIMESTAMP, 1
        )", [
            merch_uuid_ex, false, 1, req.body.info.t20_merno,
            req.body.info.t20_fee, JSON.stringify(trctl), null, null,
            req.body.info.name, req.body.info.contact,
            null, req.body.info.mobile,
            null, req.body.info.email, req.body.info.address,
            req.body.info.unit_name, req.body.info.unit_name_abbr,
            req.body.info.unit_english, req.body.info.unit_english_abbr,
            req.body.info.unit_code, req.body.info.unit_license,
            req.body.info.unit_license_exp, req.body.info.unit_tax_code,
            req.body.info.unit_issuer, req.body.info.unit_address,
            parseInt(req.body.info.unit_type) or 99, req.body.info.unit_legal_name,
            parseInt(req.body.info.unit_cred_type) or 99, req.body.info.unit_cred_no,
            parseInt(req.body.info.unit_assets) or 0, req.body.info.unit_scope,
            null, '消费商户，通过入户向导创建',
            merch_serial, merch_uuid,
            req.session.userinfo.uuid
        ], defer err, result
    if err then req.done(req.client); return next(err)
    req.t20_merch_uuid = merch_uuid
    req.t20_merch_uuid_ex = merch_uuid_ex
    next()

# 增加消费终端
router.post '/finish/p1', (req, res, next) ->
    # 添加一条终端影子记录
    term_uuid = uuid.v4()
    await req.client.query "insert into pay_terms (
            uuid, termid, merid, inputer, checker, shaded
        ) values (
            $1, $2, $3, $4, $5, true
        ) returning serial", [
            term_uuid, req.body.info.t20_termid, req.t20_merch_uuid,
            req.session.userinfo.uuid,
            req.session.userinfo.uuid
        ], defer err, result
    if err then req.done(req.client); return next(err)
    term_serial = result.rows[0].serial

    # 添加终端信息到待复核表
    term_uuid_ex = uuid.v4()
    await req.client.query "insert into pay_terms_ex (
            uuid,       termid,     merid,
            mapto_term, tmk,        macalgo,
            notes,      ref_uuid,   ref_serial,
            inputer,    input_time, action
        ) values (
            $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, CURRENT_TIMESTAMP, 1
        )", [
            term_uuid_ex, req.body.info.t20_termid, req.t20_merch_uuid,
            null, null, 1, '消费终端，通过入户向导创建',
            term_uuid, term_serial, req.session.userinfo.uuid
        ], defer err, result
    if err then req.done(req.client); return next(err)
    req.t20_term_uuid = term_uuid
    req.t20_term_uuid_ex = term_uuid_ex
    next()


# 增加代付商户
router.post '/finish/p1', (req, res, next) ->
    trctl =
        trcodes : {
            t1: true, t2: true, t3: true, t4: true, t5: true, tz0: true
        }

    # 在商户信息表中添加一条影子记录，用于终端可以引用未复核的商户
    merch_uuid = uuid.v4()
    await req.client.query "insert into pay_merch (
            shaded, uuid, inside, chnl, merno, name, trctl, inputer, checker
        ) values (
            true, $1, $2, $3, $4, $5, $6, $7, $8
        ) returning serial", [
            merch_uuid, true, 1,
            req.body.info.tz0_merno, req.body.info.name,
            JSON.stringify(trctl),
            req.session.userinfo.uuid, req.session.userinfo.uuid,
        ], defer err, result
    if err then req.done(req.client); return next(err)
    merch_serial = result.rows[0].serial

    # 添加商户信息到待复核表
    merch_uuid_ex = uuid.v4()
    await req.client.query "insert into pay_merch_ex (
            uuid,              inside,         chnl,           merno,
            t20_fee,           trctl,          settl_merid,    mapto_merid,
            name,              contact,        telephone,      mobile,
            fax,               email,          address,
            unit_name,         unit_name_abbr, unit_english,     unit_english_abbr,
            unit_code,         unit_license,   unit_license_exp, unit_tax_code,
            unit_issuer,       unit_address,   unit_type,        unit_legal_name,
            unit_cred_type,    unit_cred_no,   unit_assets,      unit_scope,
            keys,              notes,
            ref_serial,        ref_uuid,
            inputer,           input_time,     action
        ) values (
            $1, $2, $3, $4, $5, $6, $7, $8,
            $9, $10, $11, $12, $13, $14, $15,
            $16, $17, $18, $19, $20, $21, $22, $23,
            $24, $25, $26, $27, $28, $29, $30, $31,
            $32, $33,
            $34, $35,
            $36, CURRENT_TIMESTAMP, 1
        )", [
            merch_uuid_ex, true, 1, req.body.info.tz0_merno,
            req.body.info.t20_fee, JSON.stringify(trctl), null, null,
            req.body.info.name, req.body.info.contact,
            null, req.body.info.mobile,
            null, req.body.info.email, req.body.info.address,
            req.body.info.unit_name, req.body.info.unit_name_abbr,
            req.body.info.unit_english, req.body.info.unit_english_abbr,
            req.body.info.unit_code, req.body.info.unit_license,
            req.body.info.unit_license_exp, req.body.info.unit_tax_code,
            req.body.info.unit_issuer, req.body.info.unit_address,
            parseInt(req.body.info.unit_type) or 99, req.body.info.unit_legal_name,
            parseInt(req.body.info.unit_cred_type) or 99, req.body.info.unit_cred_no,
            parseInt(req.body.info.unit_assets) or 0, req.body.info.unit_scope,
            null, '消费代付商户，通过入户向导创建',
            merch_serial, merch_uuid,
            req.session.userinfo.uuid
        ], defer err, result
    if err then req.done(req.client); return next(err)
    req.tz0_merch_uuid = merch_uuid
    req.tz0_merch_uuid_ex = merch_uuid_ex
    next()


# 增加代付终端
router.post '/finish/p1', (req, res, next) ->
    # 添加一条终端影子记录
    term_uuid = uuid.v4()
    await req.client.query "insert into pay_terms (
            uuid, termid, merid, inputer, checker, shaded
        ) values (
            $1, $2, $3, $4, $5, true
        ) returning serial", [
            term_uuid, req.body.info.tz0_termid, req.tz0_merch_uuid,
            req.session.userinfo.uuid,
            req.session.userinfo.uuid
        ], defer err, result
    if err then req.done(req.client); return next(err)
    term_serial = result.rows[0].serial

    # 添加终端信息到待复核表
    term_uuid_ex = uuid.v4()
    await req.client.query "insert into pay_terms_ex (
            uuid,       termid,     merid,
            mapto_term, tmk,        macalgo,
            notes,      ref_uuid,   ref_serial,
            inputer,    input_time, action
        ) values (
            $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, CURRENT_TIMESTAMP, 1
        )", [
            term_uuid_ex, req.body.info.tz0_termid, req.tz0_merch_uuid,
            null, secure.encryptEde(req.body.info.tz0_tmk),
            parseInt(req.body.info.tz0_macalgo) or 1,
            '消费代付终端，通过入户向导创建', term_uuid, term_serial,
            req.session.userinfo.uuid
        ], defer err, result
    if err then req.done(req.client); return next(err)
    req.tz0_term_uuid = term_uuid
    req.tz0_term_uuid_ex = term_uuid_ex
    next()


# 增加消费代付配置
router.post '/finish/p1', (req, res, next) ->
    p1_uuid = uuid.v4()

    check_data = action: 1, data: {
        t20_merid:      req.t20_merch_uuid
        t20_termid:     req.t20_term_uuid
        tz0_merid:      req.tz0_merch_uuid
        tz0_termid:     req.tz0_term_uuid
        pay_chnl:       req.body.info.pay_chnl
        pay_merid:      req.body.info.pay_merid
        acct_no:        req.body.info.acct_no
        acct_name:      req.body.info.acct_name
        acct_cred_type: req.body.info.acct_cred_type
        acct_cred_no:   req.body.info.acct_cred_no
        acct_mobile:    req.body.info.acct_mobile
        acct_bank_code: req.body.info.acct_bank_code
        acct_bank_name: req.body.info.acct_bank_name
        notes:          '通过入户向导创建'
        uuid:           p1_uuid
    }
    check_data.acct_no_modified = true

    await req.client.query \
        "insert into pay_p1 (
            uuid, inputer, check_data, t20_termid, tz0_termid
        ) values (
            $1, $2, $3, $4, $5
        )", [
            p1_uuid
            req.session.userinfo.uuid
            JSON.stringify check_data
            req.t20_term_uuid
            req.tz0_term_uuid
        ], defer err, result
    if err then req.done(req.client); return next(err)
    req.p1_uuid = p1_uuid
    next()


# 增加 向导复核 记录
router.post '/finish/p1', (req, res, next) ->
    await req.client.query \
        "insert into pay_wizard (
            uuid, merch_type, merid1, termid1, merid2, termid2, p1_uuid,
            inputer
        ) values (
            $1, $2, $3, $4, $5, $6, $7, $8
        )", [
            uuid.v4()
            req.body.info.merch_type
            req.t20_merch_uuid_ex
            req.t20_term_uuid_ex
            req.tz0_merch_uuid_ex
            req.tz0_term_uuid_ex
            req.p1_uuid
            req.session.userinfo.uuid
        ], defer err, result
    if err then req.done(req.client); return next(err)
    next()


router.post '/finish/p1', (req, res, next) ->
    await req.client.query "commit", defer err, result
    req.done()
    req.app.set 'notify_modified_time', moment().format('x')
    res.json succ: true


# 助农取款商户入户检查
router.post '/finish/p2', (req, res, next) ->
    res.type 'json'
    for k in ['t60_merno', 't60_termid', 'name', 'contact', 'address',
        'tz1_merno', 'tz1_termid', 'tz1_tmk',
        't60_fee', 'p2_fund', 'fee_take_type', 'fund_lack_proc',
        'acct_no', 'pay_chnl', 'pay_merid']
        if not req.body.info[k] or req.body.info[k].length == 0
            return next(new Error("请求缺少参数[#{k}]"))

    acct_name = req.body.info.acct_name or ''
    acct_cred_no = req.body.info.acct_cred_no or ''
    if acct_name.trim().length == 0 and acct_cred_no.trim().length == 0
        return next new Error('开户人姓名与证件号码必须输入一项')

    await pgsql.connect settings.pgsql_url, defer err, client, done
    if err then done(client); return next(err)

    # 查询商户是否已经存在
    await client.query "select * from pay_merch
        where chnl = 1 and merno in ($1, $2)", [
            req.body.info.t60_merno, req.body.info.tz1_merno
        ], defer err, result
    if err then done(client); return next(err)
    if result.rows.length > 0
        done()
        return next new Error("商户 #{req.body.info.t60_merno} 或 " +
            "#{req.body.info.tz1_merno} 已存在，请检查...")

    # 查询待复核表中是否有此商户信息
    await client.query "select m.*, u.realname as user
        from pay_merch_ex as m
        left join web_users as u on u.uuid = m.inputer
        where m.chnl = 1 and m.merno in ($1, $2)", [
            req.body.info.t60_merno, req.body.info.tz1_merno
        ], defer err, result
    if err then done(client); return next(err)
    if result.rows.length > 0
        done()
        return next new Error("商户 #{req.body.info.t60_merno} 或 " +
            "#{req.body.info.tz1_merno} 已被用户 " +
            "#{result.rows[0].user} 添加，尚未复核或尚未生效")

    # 查询默认消费手续费
    await client.query \
        "select t20_fee from pay_fee_set limit 1", defer err, result
    if err then done(client); return next(err)
    done()
    if result.rows.length == 0 or not result.rows[0].t20_fee
        return next new Error('请在手续费配置页面中配置默认消费手续费.')

    req.t20_fee = result.rows[0].t20_fee
    next()


# 在一个事务中处理
router.post '/finish/p2', (req, res, next) ->
    await pgsql.connect settings.pgsql_url, defer err, client, done
    if err then done(client); return next(err)

    await client.query "begin", defer err, result
    if err then done(client); return next(err)

    req.client = client
    req.done = done
    next()

# 增加助农取款商户
router.post '/finish/p2', (req, res, next) ->
    trctl =
        t60 : {
            time_begin:     req.body.info.time_begin
            time_end:       req.body.info.time_end
            min_amt_per:    req.body.info.min_amt_per
            min_amt_per2:   req.body.info.min_amt_per2
            max_amt_per:    req.body.info.max_amt_per
            max_amt_per2:   req.body.info.max_amt_per2
            max_amt_minute: req.body.info.max_amt_minute
            max_cnt_minute: req.body.info.max_cnt_minute
            max_amt_day:    req.body.info.max_amt_day
            max_cnt_day:    req.body.info.max_cnt_day
        }
        trcodes : {
            t1: true, t2: true, t3: true, t4: true, t5: true,
            t10: true, t60: true, t22: true
        }
    # 在商户信息表中添加一条影子记录，用于终端可以引用未复核的商户
    merch_uuid = uuid.v4()
    await req.client.query "insert into pay_merch (
            shaded, uuid, inside, chnl, merno, name, trctl, inputer, checker
        ) values (
            true, $1, $2, $3, $4, $5, $6, $7, $8
        ) returning serial", [
            merch_uuid, false, 1,
            req.body.info.t60_merno, req.body.info.name,
            JSON.stringify(trctl),
            req.session.userinfo.uuid, req.session.userinfo.uuid,
        ], defer err, result
    if err then req.done(req.client); return next(err)
    merch_serial = result.rows[0].serial

    # 添加商户信息到待复核表
    merch_uuid_ex = uuid.v4()
    await req.client.query "insert into pay_merch_ex (
            uuid,              inside,         chnl,           merno,
            trctl,             settl_merid,    mapto_merid,    t20_fee,
            name,              contact,        telephone,      mobile,
            fax,               email,          address,
            unit_name,         unit_name_abbr, unit_english,     unit_english_abbr,
            unit_code,         unit_license,   unit_license_exp, unit_tax_code,
            unit_issuer,       unit_address,   unit_type,        unit_legal_name,
            unit_cred_type,    unit_cred_no,   unit_assets,      unit_scope,
            keys,              notes,
            ref_serial,        ref_uuid,
            inputer,           input_time,     action
        ) values (
            $1, $2, $3, $4, $5, $6, $7, $8,
            $9, $10, $11, $12, $13, $14, $15,
            $16, $17, $18, $19, $20, $21, $22, $23,
            $24, $25, $26, $27, $28, $29, $30, $31,
            $32, $33,
            $34, $35,
            $36, CURRENT_TIMESTAMP, 1
        )", [
            merch_uuid_ex, false, 1, req.body.info.t60_merno,
            JSON.stringify(trctl), null, null, req.t20_fee,
            req.body.info.name, req.body.info.contact,
            null, req.body.info.mobile,
            null, req.body.info.email, req.body.info.address,
            req.body.info.unit_name, req.body.info.unit_name_abbr,
            req.body.info.unit_english, req.body.info.unit_english_abbr,
            req.body.info.unit_code, req.body.info.unit_license,
            req.body.info.unit_license_exp, req.body.info.unit_tax_code,
            req.body.info.unit_issuer, req.body.info.unit_address,
            parseInt(req.body.info.unit_type) or 99, req.body.info.unit_legal_name,
            parseInt(req.body.info.unit_cred_type) or 99, req.body.info.unit_cred_no,
            parseInt(req.body.info.unit_assets) or 0, req.body.info.unit_scope,
            null, '助农取款商户，通过入户向导创建',
            merch_serial, merch_uuid,
            req.session.userinfo.uuid
        ], defer err, result
    if err then req.done(req.client); return next(err)
    req.t60_merch_uuid = merch_uuid
    req.t60_merch_uuid_ex = merch_uuid_ex
    next()


# 增加助农取款终端
router.post '/finish/p2', (req, res, next) ->
    # 添加一条终端影子记录
    term_uuid = uuid.v4()
    await req.client.query "insert into pay_terms (
            uuid, termid, merid, inputer, checker, shaded
        ) values (
            $1, $2, $3, $4, $5, true
        ) returning serial", [
            term_uuid, req.body.info.t60_termid, req.t60_merch_uuid,
            req.session.userinfo.uuid,
            req.session.userinfo.uuid
        ], defer err, result
    if err then req.done(req.client); return next(err)
    term_serial = result.rows[0].serial

    # 添加终端信息到待复核表
    term_uuid_ex = uuid.v4()
    await req.client.query "insert into pay_terms_ex (
            uuid,       termid,     merid,
            mapto_term, tmk,        macalgo,
            notes,      ref_uuid,   ref_serial,
            inputer,    input_time, action
        ) values (
            $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, CURRENT_TIMESTAMP, 1
        )", [
            term_uuid_ex, req.body.info.t60_termid, req.t60_merch_uuid,
            null, null, 1, '助农取款终端，通过入户向导创建',
            term_uuid, term_serial, req.session.userinfo.uuid
        ], defer err, result
    if err then req.done(req.client); return next(err)
    req.t60_term_uuid = term_uuid
    req.t60_term_uuid_ex = term_uuid_ex
    next()


# 增加代付商户
router.post '/finish/p2', (req, res, next) ->
    trctl =
        trcodes : {
            t1: true, t2: true, t3: true, t4: true, t5: true, tz1: true
        }

    # 在商户信息表中添加一条影子记录，用于终端可以引用未复核的商户
    merch_uuid = uuid.v4()
    await req.client.query "insert into pay_merch (
            shaded, uuid, inside, chnl, merno, name, trctl, inputer, checker
        ) values (
            true, $1, $2, $3, $4, $5, $6, $7, $8
        ) returning serial", [
            merch_uuid, true, 1,
            req.body.info.tz1_merno, req.body.info.name,
            JSON.stringify(trctl),
            req.session.userinfo.uuid, req.session.userinfo.uuid,
        ], defer err, result
    if err then req.done(req.client); return next(err)
    merch_serial = result.rows[0].serial

    # 添加商户信息到待复核表
    merch_uuid_ex = uuid.v4()
    await req.client.query "insert into pay_merch_ex (
            uuid,              inside,         chnl,           merno,
            trctl,             settl_merid,    mapto_merid,    t20_fee,
            name,              contact,        telephone,      mobile,
            fax,               email,          address,
            unit_name,         unit_name_abbr, unit_english,     unit_english_abbr,
            unit_code,         unit_license,   unit_license_exp, unit_tax_code,
            unit_issuer,       unit_address,   unit_type,        unit_legal_name,
            unit_cred_type,    unit_cred_no,   unit_assets,      unit_scope,
            keys,              notes,
            ref_serial,        ref_uuid,
            inputer,           input_time,     action
        ) values (
            $1, $2, $3, $4, $5, $6, $7, $8,
            $9, $10, $11, $12, $13, $14, $15,
            $16, $17, $18, $19, $20, $21, $22, $23,
            $24, $25, $26, $27, $28, $29, $30, $31,
            $32, $33,
            $34, $35,
            $36, CURRENT_TIMESTAMP, 1
        )", [
            merch_uuid_ex, true, 1, req.body.info.tz1_merno,
            JSON.stringify(trctl), null, null, req.t20_fee,
            req.body.info.name, req.body.info.contact,
            null, req.body.info.mobile,
            null, req.body.info.email, req.body.info.address,
            req.body.info.unit_name, req.body.info.unit_name_abbr,
            req.body.info.unit_english, req.body.info.unit_english_abbr,
            req.body.info.unit_code, req.body.info.unit_license,
            req.body.info.unit_license_exp, req.body.info.unit_tax_code,
            req.body.info.unit_issuer, req.body.info.unit_address,
            parseInt(req.body.info.unit_type) or 99, req.body.info.unit_legal_name,
            parseInt(req.body.info.unit_cred_type) or 99, req.body.info.unit_cred_no,
            parseInt(req.body.info.unit_assets) or 0, req.body.info.unit_scope,
            null, '助农取款代付商户，通过入户向导创建',
            merch_serial, merch_uuid,
            req.session.userinfo.uuid
        ], defer err, result
    if err then req.done(req.client); return next(err)
    req.tz1_merch_uuid = merch_uuid
    req.tz1_merch_uuid_ex = merch_uuid_ex
    next()


# 增加代付终端
router.post '/finish/p2', (req, res, next) ->
    # 添加一条终端影子记录
    term_uuid = uuid.v4()
    await req.client.query "insert into pay_terms (
            uuid, termid, merid, inputer, checker, shaded
        ) values (
            $1, $2, $3, $4, $5, true
        ) returning serial", [
            term_uuid, req.body.info.tz1_termid, req.tz1_merch_uuid,
            req.session.userinfo.uuid,
            req.session.userinfo.uuid
        ], defer err, result
    if err then req.done(req.client); return next(err)
    term_serial = result.rows[0].serial

    # 添加终端信息到待复核表
    term_uuid_ex = uuid.v4()
    await req.client.query "insert into pay_terms_ex (
            uuid,       termid,     merid,
            mapto_term, tmk,        macalgo,
            notes,      ref_uuid,   ref_serial,
            inputer,    input_time, action
        ) values (
            $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, CURRENT_TIMESTAMP, 1
        )", [
            term_uuid_ex, req.body.info.tz1_termid, req.tz1_merch_uuid,
            null, secure.encryptEde(req.body.info.tz1_tmk),
            parseInt(req.body.info.tz1_macalgo) or 1,
            '助农取款代付终端，通过入户向导创建', term_uuid, term_serial,
            req.session.userinfo.uuid
        ], defer err, result
    if err then req.done(req.client); return next(err)
    req.tz1_term_uuid = term_uuid
    req.tz1_term_uuid_ex = term_uuid_ex
    next()


# 增加助农取款配置
router.post '/finish/p2', (req, res, next) ->
    p2_uuid = uuid.v4()

    check_data = action: 1, data: {
        t60_merid:      req.t60_merch_uuid
        t60_termid:     req.t60_term_uuid
        tz1_merid:      req.tz1_merch_uuid
        tz1_termid:     req.tz1_term_uuid
        t60_fee:        req.body.info.t60_fee
        p2_fund:        req.body.info.p2_fund
        fee_take_type:  req.body.info.fee_take_type
        fund_lack_proc: req.body.info.fund_lack_proc
        pay_chnl:       req.body.info.pay_chnl
        pay_merid:      req.body.info.pay_merid
        acct_no:        req.body.info.acct_no
        acct_name:      req.body.info.acct_name
        acct_cred_type: req.body.info.acct_cred_type
        acct_cred_no:   req.body.info.acct_cred_no
        acct_mobile:    req.body.info.acct_mobile
        acct_bank_code: req.body.info.acct_bank_code
        acct_bank_name: req.body.info.acct_bank_name
        notes:          '通过入户向导创建'
        uuid:           p2_uuid
    }
    check_data.acct_no_modified = true

    await req.client.query \
        "insert into pay_p2 (
            uuid, inputer, check_data, t60_termid, tz1_termid
        ) values (
            $1, $2, $3, $4, $5
        )", [
            p2_uuid
            req.session.userinfo.uuid
            JSON.stringify check_data
            req.t60_term_uuid
            req.tz1_term_uuid
        ], defer err, result
    if err then req.done(req.client); return next(err)
    req.p2_uuid = p2_uuid
    next()


# 增加 向导复核 记录
router.post '/finish/p2', (req, res, next) ->
    await req.client.query \
        "insert into pay_wizard (
            uuid, merch_type, merid1, termid1, merid2, termid2, p2_uuid,
            inputer
        ) values (
            $1, $2, $3, $4, $5, $6, $7, $8
        )", [
            uuid.v4()
            req.body.info.merch_type
            req.t60_merch_uuid_ex
            req.t60_term_uuid_ex
            req.tz1_merch_uuid_ex
            req.tz1_term_uuid_ex
            req.p2_uuid
            req.session.userinfo.uuid
        ], defer err, result
    if err then req.done(req.client); return next(err)
    next()


router.post '/finish/p2', (req, res, next) ->
    await req.client.query "commit", defer err, result
    req.done()
    req.app.set 'notify_modified_time', moment().format('x')
    res.json succ: true
